package util

import (
	"context"
	"time"
)

type Backoff struct {
	ctx     context.Context
	max     time.Duration
	factor  time.Duration
	counter int
}

func NewBackoff(ctx context.Context, init, max time.Duration) *Backoff {
	return &Backoff{ctx: ctx, factor: init, max: max}
}

// Next 阻塞返回下一次重试间隔；ctx 取消立即返回 false
func (b *Backoff) Next() bool {
	d := b.factor * time.Duration(1<<uint(b.counter))
	if d > b.max {
		d = b.max
	}
	b.counter++
	select {
	case <-b.ctx.Done():
		return false
	case <-time.After(d):
		return true
	}
}
